package com.dididoctor.patient.Ui.customlistview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.dididoctor.patient.R;

import java.text.SimpleDateFormat;
import java.util.Date;


public class RefreshListView extends ListView implements OnScrollListener {

    private final String TAG = "RefreshListView";
    private int firstVisibleItemPosition; // 滚动时屏幕显示在最顶部的item的position
    private int downY = 0; // 按下时y轴的偏移量
    private int headerViewHeight; // 头布局的高度
    private View headerView; // 头布局的view对象

    private Animation upAnimation;
    private Animation downAnimation;

    private DisplayMode currentState = DisplayMode.Pull_Down; // 默认设为松开刷新的状态
    private ImageView ivArrow; // 头布局的剪头
    private TextView tvState; // 头布局的状态
    private TextView tvLastUpdateTime; // 最后刷新时间
    private ProgressBar mProgressBar; // 正在刷新中的进度条

    private OnRefreshListener mOnRefreshListener; // listview刷新的监听对象
    private boolean isToBottom = false; // 是否滚动到底部
    private boolean isLoadMoring = false; // 是否正在加载更多信息中
    private int footerViewHeight; // 脚布局的高度
    private View footerView; // 脚布局对象
    private boolean Head;
    private boolean Foot;
    private LinearLayout ll_nomore;
    private LinearLayout moreing;
    private boolean nomoreDate = false;

    public RefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);

        initHeader();

        initFooter();
        // 设置listview的滚动监听事件
        setOnScrollListener(this);

    }

    /**
     * 初始化脚布局
     */
    private void initFooter() {

//		LayoutInflater inflate = (LayoutInflater) context
//				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//		View v = inflate.inflate(
//				MResource.getIdByName(context, "layout", "newtoast"), null);
//		TextView tv = (TextView) v.findViewById(MResource.getIdByName(context,
//				"id", "text0"));
        footerView = View.inflate(getContext(), R.layout.listview_footer, null);

        measureItem(footerView); // 测量脚布局

        footerViewHeight = footerView.getMeasuredHeight();

        footerView.setPadding(0, 0, 0, -footerViewHeight); // 隐藏脚布局

        ll_nomore = (LinearLayout) footerView.findViewById(R.id.ll_nomore);
        moreing = (LinearLayout) footerView.findViewById(R.id.ll_moreing);
        moreing.setVisibility(View.VISIBLE);
        ll_nomore.setVisibility(View.GONE);
        addFooterView(footerView);
    }

    /**
     * 初始化头布局
     */
    private void initHeader() {
        headerView = View.inflate(getContext(), R.layout.listview_header, null);
        ivArrow = (ImageView) headerView
                .findViewById(R.id.iv_listview_header_arrow);
        mProgressBar = (ProgressBar) headerView
                .findViewById(R.id.pb_listview_header);
        tvState = (TextView) headerView
                .findViewById(R.id.tv_listview_header_state);
        tvLastUpdateTime = (TextView) headerView
                .findViewById(R.id.tv_listview_header_last_update_time);

        // 设置图片的最小宽度
        ivArrow.setMinimumWidth(50);
        // 设置最后刷新的时间
        tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime());

        measureItem(headerView);

        headerViewHeight = headerView.getMeasuredHeight();
        Log.i(TAG, "头布局的高度: " + headerViewHeight);

        addHeaderView(headerView); // 把headerView 添加到ListView的顶部

        headerView.setPadding(0, -headerViewHeight, 0, 0);

        initAnimation();
    }

    /**
     * 初始化动画
     */
    private void initAnimation() {
        upAnimation = new RotateAnimation(0, -180f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        upAnimation.setDuration(500);
        upAnimation.setFillAfter(true);

        downAnimation = new RotateAnimation(-180f, -360f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        downAnimation.setDuration(500);
        downAnimation.setFillAfter(true);
    }

    /**
     * 测量view的宽和高
     *
     * @param child
     */
    private void measureItem(View child) {
        ViewGroup.LayoutParams lp = child.getLayoutParams();
        if (lp == null) {
            lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        // 根据child控件的width属性得到宽度的测量规格
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
        int lpHeight = lp.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            // 根据精确的高度值来得到一个高度测量的规格
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            // 没有高度, 需要得到一个高度的测量规格
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        // 根据给定的测量规格去测量child的宽和高
        child.measure(childWidthSpec, childHeightSpec);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:

                if (currentState == DisplayMode.Refreshing)
                    return false;

                if (downY == 0)
                    downY = (int) ev.getY();

                int moveY = (int) ev.getY();

                // moveY - downY = diff
                int diff = (moveY - downY) / 2;

                // -height + diff = paddingTop
                int paddingTop = -headerViewHeight + diff;

                // 根据计算出来的paddingTop的值, 去控制头布局的显示状态
                if (firstVisibleItemPosition == 0 && paddingTop > -headerViewHeight) {
                    // Log.i(TAG, "进入头布局下拉状态");

                    if (paddingTop > 0 && currentState == DisplayMode.Pull_Down) { // 完全显示
                        Log.i(TAG, "完全显示, 执行动画进入到松开刷新的状态");

                        currentState = DisplayMode.Release_Reafresh; // 置为松开刷新状态
                        refreshHeaderViewState();
                    } else if (paddingTop < 0
                            && currentState == DisplayMode.Release_Reafresh) { // 完全隐藏
                        Log.i(TAG, "没有完全显示, 执行动画进入到下拉刷新的状态");
                        currentState = DisplayMode.Pull_Down; // 置为下拉刷新的状态
                        refreshHeaderViewState();
                    }

                    headerView.setPadding(0, paddingTop, 0, 0);
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:

                if (currentState == DisplayMode.Pull_Down) { // 当前是下拉刷新的状态,
                    // 执行隐藏头布局的操作
                    headerView.setPadding(0, -headerViewHeight, 0, 0);
                } else if (currentState == DisplayMode.Release_Reafresh) { // 当前是释放刷新的状态,
                    // 切换到正在刷新中的界面
                    currentState = DisplayMode.Refreshing; // 把当前状态改为正在刷新中
                    refreshHeaderViewState();
                    headerView.setPadding(0, 0, 0, 0); // 切换到完全显示的状态

                    if (mOnRefreshListener != null) {
                        mOnRefreshListener.onPullDownRefresh(); // 调用回调事件
                    }
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 当正在刷新的任务完成后, 调用此方法隐藏和重置头布局
     */
    public void onRefreshFinish() {

        if (!nomoreDate) {

            if (isLoadMoring) { // 加载更多
                isLoadMoring = false;
                footerView.setPadding(0, 0, 0, -footerViewHeight);
            } else { // 下拉刷新
                currentState = DisplayMode.Pull_Down;
                headerView.setPadding(0, -headerViewHeight, 0, 0);
                mProgressBar.setVisibility(View.GONE);
                ivArrow.setVisibility(View.VISIBLE);
                tvState.setText("下拉刷新");
                tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime());


            }
        } else {
            currentState = DisplayMode.Pull_Down;
            headerView.setPadding(0, -headerViewHeight, 0, 0);
            mProgressBar.setVisibility(View.GONE);
            ivArrow.setVisibility(View.VISIBLE);
            tvState.setText("下拉刷新");
            tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime());
            if (nomoreDate == true) {
                nomoreDate = false;
                isLoadMoring = false;
                moreing.setVisibility(View.VISIBLE);
                ll_nomore.setVisibility(View.GONE);
                footerView.setPadding(0, 0, 0, -footerViewHeight);
            }

        }
    }

    /**
     * 当加载更多没有数据时调用的方法
     */
    public void showNoMoreData() {
        nomoreDate = true;
        isLoadMoring = true;
        moreing.setVisibility(View.GONE);
        ll_nomore.setVisibility(View.VISIBLE);
        footerView.setPadding(0, 0, 0, 0);
    }


    /**
     * 当加载更多没有数据时调用的方法
     */
    public void showNoMoreData1() {
        nomoreDate = false;
        isLoadMoring = true;
        moreing.setVisibility(View.VISIBLE);
        ll_nomore.setVisibility(View.GONE);
        footerView.setPadding(0, 0, 0, 0);
    }


    /**
     * 当加载更多没有数据时调用的方法
     */
    public void hideNoMoreData() {
        nomoreDate = false;
        isLoadMoring = false;
        moreing.setVisibility(View.VISIBLE);
        ll_nomore.setVisibility(View.GONE);
        footerView.setPadding(0, 0, 0, -footerViewHeight);
    }


    /**
     * 获取最后刷新时间
     *
     * @return
     */
    private String getLastUpdateTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 根据currentState的值刷新头布局的状态
     */
    private void refreshHeaderViewState() {
        if (currentState == DisplayMode.Pull_Down) {
            // 下拉刷新状态
            ivArrow.startAnimation(downAnimation);
            tvState.setText("下拉刷新");
        } else if (currentState == DisplayMode.Release_Reafresh) {
            // 释放刷新
            ivArrow.startAnimation(upAnimation);
            tvState.setText("松开刷新");
        } else if (currentState == DisplayMode.Refreshing) {
            // 正在刷新中
            ivArrow.clearAnimation();
            ivArrow.setVisibility(View.GONE);
            mProgressBar.setVisibility(View.VISIBLE);
            tvState.setText("正在刷新中..");
        }
    }

    /**
     * 当listview滚动状态改变时, 回调
     *
     * @param scrollState 当前的状态 SCROLL_STATE_IDLE 空闲, 停滞 SCROLL_STATE_TOUCH_SCROLL
     *                    触摸滚动状态 SCROLL_STATE_FLING 猛地一滑
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (Foot == true) {
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
                    || scrollState == OnScrollListener.SCROLL_STATE_FLING) {
                if (!isLoadMoring) { // 当没有正在加载中进入if
                    if (isToBottom) { // 当滚动到底部时进入if
                        isLoadMoring = true;
                        Log.i(TAG, "加载更多信息");

                        footerView.setPadding(0, 0, 0, 0); // 显示脚布局
                        this.setSelection(this.getCount()); // 把最后一个position显示在界面上,
                        // 滚动到底部
                        if (mOnRefreshListener != null) {
                            mOnRefreshListener.onLoadMoring();
                        }
                    }
                }
            }
        } else {
            return;
        }

    }

    /**
     * 当listview滚动时, 回调
     *
     * @param firstVisibleItem 当前屏幕显示在最顶部的item的position
     * @param visibleItemCount 当前显示的item的总条数
     * @param totalItemCount   ListView的总条数.
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        firstVisibleItemPosition = firstVisibleItem;
        if (mOnRefreshListener != null) {
            mOnRefreshListener.onScrollListener(view, firstVisibleItem, visibleItemCount, totalItemCount);
        }
        if (firstVisibleItem + visibleItemCount == totalItemCount
                && totalItemCount > visibleItemCount) {
            // Log.i(TAG, "滚动到底部了" + "firstVisibleItem = " + firstVisibleItem
            // + ", visibleItemCount = " + visibleItemCount +
            // ", totalItemCount = " + totalItemCount);
            isToBottom = true;
        } else {
            isToBottom = false;
        }
    }

    public void setHeadAndFoot(boolean Head, boolean Foot) {
        this.Head = Head;
        this.Foot = Foot;
    }

    /**
     * 设置监听刷新的事件
     *
     * @param mOnRefreshListener
     */
    public void setOnRefreshListener(OnRefreshListener mOnRefreshListener) {
        this.mOnRefreshListener = mOnRefreshListener;
    }

    /**
     * @author andong 头布局显示的几种状态
     */
    public enum DisplayMode {
        Pull_Down, // 松开刷新的状态
        Release_Reafresh, // 释放刷新
        Refreshing // 正在刷新中
    }
}
